/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

package xowl.gmi.view;

/**
 *
 * @author Laurent WOUTERS
 */
public class DragDropUtil {
    public static void setTarget(final javax.swing.JComponent component, final DragHandler drag, final DropHandler drop) {
        final java.awt.Point dragLocation = new java.awt.Point();
        final javax.swing.TransferHandler th = new javax.swing.TransferHandler(null) {
            @Override public int getSourceActions(javax.swing.JComponent c) {
                if (drag != null)
                    return drag.getAction();
                return javax.swing.TransferHandler.NONE;
            }
            @Override public java.awt.datatransfer.Transferable createTransferable(javax.swing.JComponent c) {
                if (drag == null)
                    return null;
                return new java.awt.datatransfer.Transferable() {
                    @Override public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
                        return new java.awt.datatransfer.DataFlavor[] { drag.getDataFlavor() };
                    }
                    @Override public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
                        return (drag.getDataFlavor() == flavor);
                    }
                    @Override public Object getTransferData(java.awt.datatransfer.DataFlavor flavor) throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException {
                        return drag.getTransferable();
                    }
                };
            }
            @Override public void exportDone(javax.swing.JComponent c, java.awt.datatransfer.Transferable t, int action) {
                if (drag != null) {
                    try {
                        drag.onDragDropEnd(t.getTransferData(drag.getDataFlavor()), action);
                    }
                    catch (java.awt.datatransfer.UnsupportedFlavorException | java.io.IOException ex) { }
                }
            }
            @Override public java.awt.Image getDragImage() {
                if (drag == null)
                    return null;
                return drag.getImage();
            }
            @Override public java.awt.Point getDragImageOffset() { return dragLocation; }
            @Override public boolean canImport(javax.swing.TransferHandler.TransferSupport support) {
                if (drop == null)
                    return false;
                if ((support.getSourceDropActions() & drop.getSupportedActions()) == 0)
                    return false;
                java.awt.datatransfer.DataFlavor[] flavors = support.getDataFlavors();
                for (int i=0; i!=flavors.length; i++) {
                    if (drop.acceptFlavor(flavors[i])) {
                        try {
                            Object data = support.getTransferable().getTransferData(flavors[i]);
                            if (drop.acceptData(flavors[i], data))
                                return true;
                        }
                        catch (java.awt.datatransfer.UnsupportedFlavorException | java.io.IOException ex) { }
                    }
                }
                return false;
            }
            @Override public boolean importData(javax.swing.TransferHandler.TransferSupport support) {
                if (drop == null)
                    return false;
                if ((support.getSourceDropActions() & drop.getSupportedActions()) == 0)
                    return false;
                java.awt.datatransfer.DataFlavor[] flavors = support.getDataFlavors();
                for (int i=0; i!=flavors.length; i++) {
                    if (drop.acceptFlavor(flavors[i])) {
                        try {
                            Object data = support.getTransferable().getTransferData(flavors[i]);
                            if (drop.acceptData(flavors[i], data)) {
                                if (drop.drop(flavors[i], data, support.getDropLocation().getDropPoint()))
                                    return true;
                            }
                        }
                        catch (java.awt.datatransfer.UnsupportedFlavorException | java.io.IOException ex) { }
                    }
                }
                return false;
            }
        };
        if (drag != null) {
            component.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
                @Override public void mouseDragged(java.awt.event.MouseEvent e) {
                    dragLocation.x = e.getX();
                    dragLocation.y = e.getY();
                    drag.onDragStart(new java.awt.Point(e.getX(), e.getY()));
                    th.exportAsDrag(component, e, drag.getAction());
                }
            });
        }
        component.setTransferHandler(th);
    }
}
